package com.tarena.demo.luban.gateway.filters;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.server.RequestPath;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.function.Supplier;

@Slf4j
//@Component
public class MyFilter01 implements GlobalFilter, Ordered {
    /**
     * 网关过滤器过滤逻辑执行方法
     * 只要当前过滤器类型在网关生效,所有的请求 都会经过这个方法
     * exchange: 包装了请求和响应等数据的对象
     * chain: 表示当前过滤器所在的过滤链.
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("请求经过了MyFilter01");
        // 获取请求
        ServerHttpRequest request = exchange.getRequest();
        // 1.获取请求路径
        RequestPath path = request.getPath();
        log.info("请求路径：{}",path);
        // 2.获取访问全路径地址URI
        URI uri = request.getURI();
        log.info("请求URI：{}",uri);
        // 3.获取查询参数
        MultiValueMap<String, String> queryParams = request.getQueryParams();
        List<String> names = queryParams.get("name");
        log.info("请求参数：{}",names);
//        List<String> ages = queryParams.get("age");
//        log.info("请求参数：{}",ages);
        // 4.获取请求头
        HttpHeaders headers = request.getHeaders();
        log.info("请求头：{}",headers);
        InetSocketAddress host = headers.getHost();
        log.info("请求主机：{}",host);
        List<MediaType> accept = headers.getAccept();
        log.info("请求头Accept：{}",accept);
        // 5.获取cookie
        MultiValueMap<String, HttpCookie> cookies = request.getCookies();
        log.info("请求cookie：{}",cookies);
        // 获取指定的cookie
        List<HttpCookie> location = cookies.get("location");
        log.info("请求指定cookie：{}",location);
        // 6.获取发出请求的客户端IP（网安相关）
        InetSocketAddress remoteAddress = request.getRemoteAddress();
        log.info("请求客户端IP：{}",remoteAddress);

        // 使用响应对象输出数据
        String message = "请求被MyFilter01过滤了";
        // 1.获取响应对象
        ServerHttpResponse response = exchange.getResponse();
        // 2.输出中文内容的对象要处理乱码问题，设置一个响应头
        response.getHeaders().setContentType(MediaType.APPLICATION_JSON_UTF8);
        // 3.创建工厂对象
        DataBufferFactory factory = response.bufferFactory();
        DataBuffer dataBuffer = factory.wrap(message.getBytes(StandardCharsets.UTF_8));
        // 4.创建response可以输出的对象，包装dataBuffer
        Mono<DataBuffer> writeResult = Mono.fromSupplier(
                new Supplier<DataBuffer>() {
                    @Override
                    public DataBuffer get() {
                        return dataBuffer;
                    }
                }
        );
        // 5.输出响应
        return response.writeWith(writeResult);
    }

    /**
     * 获取过滤器执行顺序
     * @return int 过滤器执行顺序，数值越小，优先级越高
     */
    @Override
    public int getOrder() {
        return 100;
    }
}
